<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.4"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Flow: flow::perf Namespace Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">Flow<span id="projectnumber">&#160;2.0.0</span>
   </div>
   <div id="projectbrief">Flow project: Full implementation reference.</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.4 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search",'Search','.html');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespaceflow.html">flow</a></li><li class="navelem"><a class="el" href="namespaceflow_1_1perf.html">perf</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#nested-classes">Classes</a> &#124;
<a href="#typedef-members">Typedefs</a> &#124;
<a href="#enum-members">Enumerations</a> &#124;
<a href="#func-members">Functions</a>  </div>
  <div class="headertitle"><div class="title">flow::perf Namespace Reference</div></div>
</div><!--header-->
<div class="contents">

<p>Flow module containing tools for profiling and optimization.  
<a href="namespaceflow_1_1perf.html#details">More...</a></p>
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
Classes</h2></td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">The central class in the <code>perf</code> Flow module, this efficiently times the user's operation, with a specified subset of timing methods; and with the optional ability to time intermediate <em>checkpoints</em> within the overall operation.  <a href="classflow_1_1perf_1_1Checkpointing__timer.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Convenience wrapper around an <code>array&lt;Duration, N&gt;</code>, which stores a duration for each of the N possible clock types in <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a>.  <a href="structflow_1_1perf_1_1Duration__set.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a></td></tr>
<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Convenience wrapper around an <code>array&lt;Time_pt, N&gt;</code>, which stores a time point for each of the N possible clock types in <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a>.  <a href="structflow_1_1perf_1_1Time__pt__set.html#details">More...</a><br /></td></tr>
<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="typedef-members" name="typedef-members"></a>
Typedefs</h2></td></tr>
<tr class="memitem:ace5f154155a7d9d5c112c1a83aa04fb5"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#ace5f154155a7d9d5c112c1a83aa04fb5">Time_pt</a> = <a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8">Fine_time_pt</a></td></tr>
<tr class="memdesc:ace5f154155a7d9d5c112c1a83aa04fb5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for a high-precision boost.chrono point in time, formally equivalent to <a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8" title="A high-res time point as returned by Fine_clock::now() and suitable for precise time math in general.">flow::Fine_time_pt</a>.  <a href="namespaceflow_1_1perf.html#ace5f154155a7d9d5c112c1a83aa04fb5">More...</a><br /></td></tr>
<tr class="separator:ace5f154155a7d9d5c112c1a83aa04fb5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a38e42ae0923eb23052e3a8a1e7956456"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456">Duration</a> = <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79">Fine_duration</a></td></tr>
<tr class="memdesc:a38e42ae0923eb23052e3a8a1e7956456"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for a high-precision boost.chrono duration, formally equivalent to <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">flow::Fine_duration</a>.  <a href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456">More...</a><br /></td></tr>
<tr class="separator:a38e42ae0923eb23052e3a8a1e7956456"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a75b06c669e720c60621f3c68c3d34408"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a75b06c669e720c60621f3c68c3d34408">duration_rep_t</a> = Duration::rep</td></tr>
<tr class="memdesc:a75b06c669e720c60621f3c68c3d34408"><td class="mdescLeft">&#160;</td><td class="mdescRight">The raw type used in <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">Duration</a> to store its clock ticks.  <a href="namespaceflow_1_1perf.html#a75b06c669e720c60621f3c68c3d34408">More...</a><br /></td></tr>
<tr class="separator:a75b06c669e720c60621f3c68c3d34408"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aabd93a8a40158585ed149742d8937601"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">Clock_types_subset</a> = std::bitset&lt; size_t(<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a6fba12db09e5bebfaa04f6372c41c2cf">Clock_type::S_END_SENTINEL</a>)&gt;</td></tr>
<tr class="memdesc:aabd93a8a40158585ed149742d8937601"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for a bit-set of N bits which represents the presence or absence of each of the N possible clock types in <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a>.  <a href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">More...</a><br /></td></tr>
<tr class="separator:aabd93a8a40158585ed149742d8937601"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a09ba385403a0f347f283659a6e9d971b"><td class="memItemLeft" align="right" valign="top">using&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a09ba385403a0f347f283659a6e9d971b">Checkpointing_timer_ptr</a> = boost::shared_ptr&lt; <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &gt;</td></tr>
<tr class="memdesc:a09ba385403a0f347f283659a6e9d971b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Short-hand for ref-counting pointer to <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a>.  <a href="namespaceflow_1_1perf.html#a09ba385403a0f347f283659a6e9d971b">More...</a><br /></td></tr>
<tr class="separator:a09ba385403a0f347f283659a6e9d971b"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="enum-members" name="enum-members"></a>
Enumerations</h2></td></tr>
<tr class="memitem:ad61fb186191e4bb824d14601d11a2eb0"><td class="memItemLeft" align="right" valign="top">enum class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a> : size_t { <br />
&#160;&#160;<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a8cbf506eda585c026dfb5b72c402d342">S_REAL_HI_RES</a> = 0
, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0ae06b569eb44aff6a567186f4eddb12ed">S_CPU_USER_LO_RES</a>
, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a1490431155a134162390180995550ca7">S_CPU_SYS_LO_RES</a>
, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0ac5c54159101dbdb580f0b16a9397d6f3">S_CPU_TOTAL_HI_RES</a>
, <br />
&#160;&#160;<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2">S_CPU_THREAD_TOTAL_HI_RES</a>
, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a6fba12db09e5bebfaa04f6372c41c2cf">S_END_SENTINEL</a>
<br />
 }</td></tr>
<tr class="memdesc:ad61fb186191e4bb824d14601d11a2eb0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Clock types supported by <a class="el" href="namespaceflow_1_1perf.html" title="Flow module containing tools for profiling and optimization.">flow::perf</a> module facilities, perf::Checkpointing_timer in particular.  <a href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">More...</a><br /></td></tr>
<tr class="separator:ad61fb186191e4bb824d14601d11a2eb0"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="func-members" name="func-members"></a>
Functions</h2></td></tr>
<tr class="memitem:a5bb3a068357516df714c4266ec5c3df4"><td class="memItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a5bb3a068357516df714c4266ec5c3df4">operator&lt;&lt;</a> (std::ostream &amp;os, const <a class="el" href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html">Checkpointing_timer::Checkpoint</a> &amp;checkpoint)</td></tr>
<tr class="memdesc:a5bb3a068357516df714c4266ec5c3df4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation of the given <code>Checkpoint</code> to the given <code>ostream</code>.  <a href="namespaceflow_1_1perf.html#a5bb3a068357516df714c4266ec5c3df4">More...</a><br /></td></tr>
<tr class="separator:a5bb3a068357516df714c4266ec5c3df4"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a6d5b7cbbe0ec5133299f97148ef3eaa0"><td class="memItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a6d5b7cbbe0ec5133299f97148ef3eaa0">operator&lt;&lt;</a> (std::ostream &amp;os, const <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;timer)</td></tr>
<tr class="memdesc:a6d5b7cbbe0ec5133299f97148ef3eaa0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation of the given <code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a></code> (whether with original data or an aggregated-result timer) to the given <code>ostream</code>.  <a href="namespaceflow_1_1perf.html#a6d5b7cbbe0ec5133299f97148ef3eaa0">More...</a><br /></td></tr>
<tr class="separator:a6d5b7cbbe0ec5133299f97148ef3eaa0"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af4b93cb0638c3d0bcfcf36903f0a3e46"><td class="memItemLeft" align="right" valign="top"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#af4b93cb0638c3d0bcfcf36903f0a3e46">operator-</a> (const <a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> &amp;to, const <a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> &amp;from)</td></tr>
<tr class="memdesc:af4b93cb0638c3d0bcfcf36903f0a3e46"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> representing the time that passed since <code>from</code> to <code>to</code> (negative if <code>to</code> happened earlier), for each <code>Clock_type</code> stored.  <a href="namespaceflow_1_1perf.html#af4b93cb0638c3d0bcfcf36903f0a3e46">More...</a><br /></td></tr>
<tr class="separator:af4b93cb0638c3d0bcfcf36903f0a3e46"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1c1e96770f8264d938ac09546a7cdb95"><td class="memItemLeft" align="right" valign="top"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a1c1e96770f8264d938ac09546a7cdb95">operator+=</a> (<a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;target, const <a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;to_add)</td></tr>
<tr class="memdesc:a1c1e96770f8264d938ac09546a7cdb95"><td class="mdescLeft">&#160;</td><td class="mdescRight">Advances each <code>Duration</code> in the target <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> by the given respective addend <code>Duration</code>s (negative Duration causes advancing backwards).  <a href="namespaceflow_1_1perf.html#a1c1e96770f8264d938ac09546a7cdb95">More...</a><br /></td></tr>
<tr class="separator:a1c1e96770f8264d938ac09546a7cdb95"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a46efb90b848b87bb7bbaa3e415616e6e"><td class="memItemLeft" align="right" valign="top"><a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a46efb90b848b87bb7bbaa3e415616e6e">operator+=</a> (<a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> &amp;target, const <a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;to_add)</td></tr>
<tr class="memdesc:a46efb90b848b87bb7bbaa3e415616e6e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Advances each <code>Time_pt</code> in the target <a class="el" href="structflow_1_1perf_1_1Time__pt__set.html" title="Convenience wrapper around an array&lt;Time_pt, N&gt;, which stores a time point for each of the N possible...">Time_pt_set</a> by the given respective addend <code>Duration</code>s (negative <code>Duration</code> causes advancing backwards).  <a href="namespaceflow_1_1perf.html#a46efb90b848b87bb7bbaa3e415616e6e">More...</a><br /></td></tr>
<tr class="separator:a46efb90b848b87bb7bbaa3e415616e6e"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a129032bde1082e8f2681669acf6bf03d"><td class="memItemLeft" align="right" valign="top"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a129032bde1082e8f2681669acf6bf03d">operator*=</a> (<a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;target, uint64_t mult_scale)</td></tr>
<tr class="memdesc:a129032bde1082e8f2681669acf6bf03d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Scales each <code>Duration</code> in the target <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> by the given numerical constant.  <a href="namespaceflow_1_1perf.html#a129032bde1082e8f2681669acf6bf03d">More...</a><br /></td></tr>
<tr class="separator:a129032bde1082e8f2681669acf6bf03d"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aff603762f38b9e3e3d50b833e09c3f91"><td class="memItemLeft" align="right" valign="top"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#aff603762f38b9e3e3d50b833e09c3f91">operator/=</a> (<a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;target, uint64_t div_scale)</td></tr>
<tr class="memdesc:aff603762f38b9e3e3d50b833e09c3f91"><td class="mdescLeft">&#160;</td><td class="mdescRight">Divides each <code>Duration</code> in the target <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> by the given numerical constant.  <a href="namespaceflow_1_1perf.html#aff603762f38b9e3e3d50b833e09c3f91">More...</a><br /></td></tr>
<tr class="separator:aff603762f38b9e3e3d50b833e09c3f91"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:aa26027bcba9c000350811727f0a8fc21"><td class="memItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#aa26027bcba9c000350811727f0a8fc21">operator&lt;&lt;</a> (std::ostream &amp;os, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a> clock_type)</td></tr>
<tr class="memdesc:aa26027bcba9c000350811727f0a8fc21"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation of the given clock type <code>enum</code> value to the given <code>ostream</code>.  <a href="namespaceflow_1_1perf.html#aa26027bcba9c000350811727f0a8fc21">More...</a><br /></td></tr>
<tr class="separator:aa26027bcba9c000350811727f0a8fc21"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a4cff304aa30be9d5810f90101d32b761"><td class="memItemLeft" align="right" valign="top">std::ostream &amp;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a4cff304aa30be9d5810f90101d32b761">operator&lt;&lt;</a> (std::ostream &amp;os, const <a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;duration_set)</td></tr>
<tr class="memdesc:a4cff304aa30be9d5810f90101d32b761"><td class="mdescLeft">&#160;</td><td class="mdescRight">Prints string representation of the given <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> value to the given <code>ostream</code>.  <a href="namespaceflow_1_1perf.html#a4cff304aa30be9d5810f90101d32b761">More...</a><br /></td></tr>
<tr class="separator:a4cff304aa30be9d5810f90101d32b761"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a0dee22ec7bf250bbbf556a7e15c1f784"><td class="memTemplParams" colspan="2">template&lt;typename Accumulator , typename Func &gt; </td></tr>
<tr class="memitem:a0dee22ec7bf250bbbf556a7e15c1f784"><td class="memTemplItemLeft" align="right" valign="top">auto&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784">timed_function</a> (<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a> clock_type, Accumulator *accumulator, Func &amp;&amp;function)</td></tr>
<tr class="memdesc:a0dee22ec7bf250bbbf556a7e15c1f784"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs a closure that times and executes <code>void</code>-returning <code>function()</code>, adding the elapsed time with clock type <code>clock_type</code> &ndash; as raw ticks of <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">perf::Duration</a> &ndash; to <code>accumulator</code>.  <a href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784">More...</a><br /></td></tr>
<tr class="separator:a0dee22ec7bf250bbbf556a7e15c1f784"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a58d2f7a7fca0c3cfd0a87ae560ce4926"><td class="memTemplParams" colspan="2">template&lt;typename Accumulator , typename Func &gt; </td></tr>
<tr class="memitem:a58d2f7a7fca0c3cfd0a87ae560ce4926"><td class="memTemplItemLeft" align="right" valign="top">auto&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a58d2f7a7fca0c3cfd0a87ae560ce4926">timed_function_nvr</a> (<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a> clock_type, Accumulator *accumulator, Func &amp;&amp;function)</td></tr>
<tr class="memdesc:a58d2f7a7fca0c3cfd0a87ae560ce4926"><td class="mdescLeft">&#160;</td><td class="mdescRight">Constructs a closure that times and executes non-<code>void</code>-returning <code>function()</code>, adding the elapsed time with clock type <code>clock_type</code> &ndash; as raw ticks of <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">perf::Duration</a> &ndash; to <code>accumulator</code>.  <a href="namespaceflow_1_1perf.html#a58d2f7a7fca0c3cfd0a87ae560ce4926">More...</a><br /></td></tr>
<tr class="separator:a58d2f7a7fca0c3cfd0a87ae560ce4926"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7a3694bcd6e4bd506715d5931bc0c009"><td class="memTemplParams" colspan="2">template&lt;typename Accumulator , typename Handler &gt; </td></tr>
<tr class="memitem:a7a3694bcd6e4bd506715d5931bc0c009"><td class="memTemplItemLeft" align="right" valign="top">auto&#160;</td><td class="memTemplItemRight" valign="bottom"><a class="el" href="namespaceflow_1_1perf.html#a7a3694bcd6e4bd506715d5931bc0c009">timed_handler</a> (<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a> clock_type, Accumulator *accumulator, Handler &amp;&amp;handler)</td></tr>
<tr class="memdesc:a7a3694bcd6e4bd506715d5931bc0c009"><td class="mdescLeft">&#160;</td><td class="mdescRight">Identical to <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a> but suitable for boost.asio-targeted handler functions.  <a href="namespaceflow_1_1perf.html#a7a3694bcd6e4bd506715d5931bc0c009">More...</a><br /></td></tr>
<tr class="separator:a7a3694bcd6e4bd506715d5931bc0c009"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
<div class="textblock"><p >Flow module containing tools for profiling and optimization. </p>
<p >As of this writing (around the time the <a class="el" href="namespaceflow_1_1perf.html" title="Flow module containing tools for profiling and optimization.">flow::perf</a> Flow module was created) this centers on <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a>, a facility for measuring real and processor time elapsed during the arbitrary measured operation. That said, generally speaking, this module is meant to be a "kitchen-sink" set of facilities fitting the sentence at the very top of this doc header. </p>
</div><h2 class="groupheader">Typedef Documentation</h2>
<a id="a09ba385403a0f347f283659a6e9d971b" name="a09ba385403a0f347f283659a6e9d971b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a09ba385403a0f347f283659a6e9d971b">&#9670;&nbsp;</a></span>Checkpointing_timer_ptr</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1perf.html#a09ba385403a0f347f283659a6e9d971b">flow::perf::Checkpointing_timer_ptr</a> = typedef boost::shared_ptr&lt;<a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a>&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for ref-counting pointer to <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a>. </p>
<p >Original use case is to allow <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer_1_1Aggregator.html" title="This companion/inner class of Checkpointing_timer provides aggregation of results from many Checkpoin...">Checkpointing_timer::Aggregator</a> to generate and return <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a> objects with minimal headaches for user. </p>

<p class="definition">Definition at line <a class="el" href="perf__fwd_8hpp_source.html#l00043">43</a> of file <a class="el" href="perf__fwd_8hpp_source.html">perf_fwd.hpp</a>.</p>

</div>
</div>
<a id="aabd93a8a40158585ed149742d8937601" name="aabd93a8a40158585ed149742d8937601"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aabd93a8a40158585ed149742d8937601">&#9670;&nbsp;</a></span>Clock_types_subset</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601">flow::perf::Clock_types_subset</a> = typedef std::bitset&lt;size_t(<a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a6fba12db09e5bebfaa04f6372c41c2cf">Clock_type::S_END_SENTINEL</a>)&gt;</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for a bit-set of N bits which represents the presence or absence of each of the N possible clock types in <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a>. </p>
<p >This is what we use to represent such things, as it is more compact and (we suspect) faster in typical operations, especially "is clock type T enabled?".</p>
<p >If C is a <code>Clock_types_subset</code>, and T is a <code>Clock_type</code>, then bit C[size_t(T)] is <code>true</code> if and only if T is in C.</p>
<p >Potential gotcha: bit-sets are indexed right-to-left (LSB-to-MSB); so if the 0th (in <code>enum</code>) clock type is enabled and others are disabled, then a print-out of such a Clock_types_subset would be 0...0001, not 1000...0. So watch out when reading logs. </p>

<p class="definition">Definition at line <a class="el" href="clock__type__fwd_8hpp_source.html#l00164">164</a> of file <a class="el" href="clock__type__fwd_8hpp_source.html">clock_type_fwd.hpp</a>.</p>

</div>
</div>
<a id="a38e42ae0923eb23052e3a8a1e7956456" name="a38e42ae0923eb23052e3a8a1e7956456"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a38e42ae0923eb23052e3a8a1e7956456">&#9670;&nbsp;</a></span>Duration</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456">flow::perf::Duration</a> = typedef <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79">Fine_duration</a></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for a high-precision boost.chrono duration, formally equivalent to <a class="el" href="namespaceflow.html#a48799f1263cdeedec125be51a3db2b79" title="A high-res time duration as computed from two Fine_time_pts.">flow::Fine_duration</a>. </p>
<p >The alias exists 1/2 for brevity, 1/2 to declare the standardly-used duration type in <a class="el" href="namespaceflow_1_1perf.html" title="Flow module containing tools for profiling and optimization.">flow::perf</a> Flow module. </p>

<p class="definition">Definition at line <a class="el" href="clock__type__fwd_8hpp_source.html#l00039">39</a> of file <a class="el" href="clock__type__fwd_8hpp_source.html">clock_type_fwd.hpp</a>.</p>

</div>
</div>
<a id="a75b06c669e720c60621f3c68c3d34408" name="a75b06c669e720c60621f3c68c3d34408"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a75b06c669e720c60621f3c68c3d34408">&#9670;&nbsp;</a></span>duration_rep_t</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1perf.html#a75b06c669e720c60621f3c68c3d34408">flow::perf::duration_rep_t</a> = typedef Duration::rep</td>
        </tr>
      </table>
</div><div class="memdoc">

<p>The raw type used in <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">Duration</a> to store its clock ticks. </p>
<p >It is likely <code>int64_t</code>, but try not to rely on that directly.</p>
<h3>Rationale</h3>
<p >Useful, e.g., in <code>atomic&lt;duration_rep_t&gt;</code>, when one wants to perform high-performance operations like <code>+=</code> and <code>fetch_add()</code> on <code>atomic&lt;&gt;</code>s: these do not exist for <code>chrono::duration</code>, because the latter is not an integral type. </p>

<p class="definition">Definition at line <a class="el" href="clock__type__fwd_8hpp_source.html#l00050">50</a> of file <a class="el" href="clock__type__fwd_8hpp_source.html">clock_type_fwd.hpp</a>.</p>

</div>
</div>
<a id="ace5f154155a7d9d5c112c1a83aa04fb5" name="ace5f154155a7d9d5c112c1a83aa04fb5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ace5f154155a7d9d5c112c1a83aa04fb5">&#9670;&nbsp;</a></span>Time_pt</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">using <a class="el" href="namespaceflow_1_1perf.html#ace5f154155a7d9d5c112c1a83aa04fb5">flow::perf::Time_pt</a> = typedef <a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8">Fine_time_pt</a></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Short-hand for a high-precision boost.chrono point in time, formally equivalent to <a class="el" href="namespaceflow.html#a9d9cc2eeb10d398cff5591d446b763b8" title="A high-res time point as returned by Fine_clock::now() and suitable for precise time math in general.">flow::Fine_time_pt</a>. </p>
<p >The alias exists 1/2 for brevity, 1/2 to declare the standardly-used time point type in <a class="el" href="namespaceflow_1_1perf.html" title="Flow module containing tools for profiling and optimization.">flow::perf</a> Flow module. </p>

<p class="definition">Definition at line <a class="el" href="clock__type__fwd_8hpp_source.html#l00033">33</a> of file <a class="el" href="clock__type__fwd_8hpp_source.html">clock_type_fwd.hpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Enumeration Type Documentation</h2>
<a id="ad61fb186191e4bb824d14601d11a2eb0" name="ad61fb186191e4bb824d14601d11a2eb0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ad61fb186191e4bb824d14601d11a2eb0">&#9670;&nbsp;</a></span>Clock_type</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">enum class <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">flow::perf::Clock_type</a> : size_t</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">strong</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">

<p>Clock types supported by <a class="el" href="namespaceflow_1_1perf.html" title="Flow module containing tools for profiling and optimization.">flow::perf</a> module facilities, <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">perf::Checkpointing_timer</a> in particular. </p>
<p >These are used, among other things, as array/<code>vector</code> indices and therefore numerically equal 0, 1, .... <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a6fba12db09e5bebfaa04f6372c41c2cf" title="Final, invalid clock type; its numerical value equals the number of clocks currently supported.">Clock_type::S_END_SENTINEL</a> is an invalid clock type whose numerical value equals the number of clock types available.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000144">Todo:</a></b></dt><dd>Consider adding a system-calendar-clock (a/k/a POSIX time) type to <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a>. It would be a cousin of <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a8cbf506eda585c026dfb5b72c402d342" title="Measures real time (not processor time), using the highest-resolution system clock available that gua...">Clock_type::S_REAL_HI_RES</a>. It would certainly be inferior in terms of resolution/monotonicity/etc., and one would think <code>S_REAL_HI_RES</code> would always be preferable. Nevertheless it would be interesting to "officially" see its characteristics including in particular (1) resolution and (2) its own perf cost especially vs. <code>S_REAL_HI_RES</code> which we know is quite fast itself. This may also help a certain to-do listed as of this writing in the doc header of <a class="el" href="namespaceflow_1_1log.html" title="Flow module providing logging functionality.">flow::log</a> <a class="el" href="log_8hpp.html#a5daa2b6d16edea74bb8bddc75f7fb801" title="Identical to FLOW_LOG_WITH_CHECKING() but foregoes the filter (Logger::should_log()) check.">FLOW_LOG_WITHOUT_CHECKING()</a> (the main worker bee of the log system, the one that generates each log time stamp). </dd></dl>
<table class="fieldtable">
<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="ad61fb186191e4bb824d14601d11a2eb0a8cbf506eda585c026dfb5b72c402d342" name="ad61fb186191e4bb824d14601d11a2eb0a8cbf506eda585c026dfb5b72c402d342"></a>S_REAL_HI_RES&#160;</td><td class="fielddoc"><p >Measures real time (not processor time), using the highest-resolution system clock available that guarantees steady, monotonic time passage with no discontinuities. </p>
<p >In POSIX <code>"::clock_gettime(CLOCK_MONOTONIC)"</code> is the underlying native mechanism as of this writing.</p>
<h3>Obervations, informal suggestions</h3>
<p >Of all clocks observed so far, it has the best resolution and also is the cheapest computationally itself. However, it measures real time, so (for example) another thread or process pegging the processor concurrently can affect the time being measured. That, in particular, is not necessarily a problem in test rigs; but even so it cannot measure (for example) how costly one thread is over another; nor does it separate idle time from computing time from I/O time from....</p>
<p >Due to the high resolution and low computational cost, one should strive to use this clock whenever possible; but it is not always possible (as additional info may be required, as outlined just above). </p>
</td></tr>
<tr><td class="fieldname"><a id="ad61fb186191e4bb824d14601d11a2eb0ae06b569eb44aff6a567186f4eddb12ed" name="ad61fb186191e4bb824d14601d11a2eb0ae06b569eb44aff6a567186f4eddb12ed"></a>S_CPU_USER_LO_RES&#160;</td><td class="fielddoc"><p >Along with <code>S_CPU_SYS_LO_RES</code>, measures processor time (user-level) spent by the current <em>process</em>; this is the lower-resolution timer facility as in the <code>time</code> POSIX command. </p>
<p >In POSIX <code>"::times()"</code> is the underlying native mechanism as of this writing.</p>
<h3>Obervations, informal suggestions</h3>
<p ><code>S_CPU_TOTAL_HI_RES</code> is the superior processor-time clock; we have observed it to be equally computationally expensive but delivering higher-resolution results. However, it doesn't provide the classic user-kernel split the way <code>S_CPU_SYS_LO_RES</code> and <code>S_CPU_USER_LO_RES</code> do together.</p>
<p >See discussion on <code>S_CPU_TOTAL_HI_RES</code> regarding when/if to use process-time clocks. </p>
</td></tr>
<tr><td class="fieldname"><a id="ad61fb186191e4bb824d14601d11a2eb0a1490431155a134162390180995550ca7" name="ad61fb186191e4bb824d14601d11a2eb0a1490431155a134162390180995550ca7"></a>S_CPU_SYS_LO_RES&#160;</td><td class="fielddoc"><p >Counterpart of <code>S_CPU_USER_LO_RES</code>, measuring processor time (kernel-level) spent by the current <em>process</em>. </p>
</td></tr>
<tr><td class="fieldname"><a id="ad61fb186191e4bb824d14601d11a2eb0ac5c54159101dbdb580f0b16a9397d6f3" name="ad61fb186191e4bb824d14601d11a2eb0ac5c54159101dbdb580f0b16a9397d6f3"></a>S_CPU_TOTAL_HI_RES&#160;</td><td class="fielddoc"><p >Measures processor time (user- and kernel-level total) spent by the current <em>process</em>; this is the higher-resolution process-time facility. </p>
<p >In POSIX <code>"::clock_gettime(CLOCK_PROCESS_CPUTIME_ID)"</code> is the underlying native mechanism as of this writing.</p>
<h3>Obervations, informal suggestions</h3>
<p >Firstly see <code>S_REAL_HI_RES</code> and ensure that one isn't sufficient for your needs, as it is much more accurate and computationally cheaper by 1-2 orders of magnitude based on our observations in Mac and Linux runs.</p>
<p >Processor time actually measures processor <em>cycles</em> being spent to make computations. (I/O ops and idle time are not counted.) Every cycle spent by any processor core is either charged to this process or another process; if the former then it's counted; otherwise it isn't. Next, the cycle count is multiplied by its standard constant time duration (which is based directly on the clock frequency, the GHz thing). That is the result. Multiple threads acting concurrently would all count if present, so remember that. Further, it is apparently not straightforward what the system will charge to process A vs. process B. For this reason, processor-time results of very short operations (on the order of, like, a few system calls, say) are notoriously inconsistent: <em>you should strive to measure longer operations, or operation repeated many times in a row</em>. This stands in stark contrast to <code>S_REAL_HI_RES</code> which &ndash; concurrent processor pegging aside (can usually be avoided in test rigs) &ndash; tends to be both accurate and consistent. In addition, the get-time call itself can be relatively expensive and can affect the overall efficiency of an algorithm even as one tries to measure its different parts (again: avoid such problems by measuring longer things).</p>
<p >See also <code>S_CPU_THREAD_TOTAL_HI_RES</code> if one desires per-thread timing as opposed to per-process. </p>
</td></tr>
<tr><td class="fieldname"><a id="ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2" name="ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2"></a>S_CPU_THREAD_TOTAL_HI_RES&#160;</td><td class="fielddoc"><p >Similar to <code>S_CPU_TOTAL_HI_RES</code> but applied to the calling thread as opposed to entire process. </p>
<p >In POSIX <code>"::clock_gettime(CLOCK_THREAD_CPUTIME_ID)"</code> is the underlying native mechanism as of this writing.</p>
<h3>Obervations, informal suggestions</h3>
<p >See <code>S_CPU_TOTAL_HI_RES</code>, as those comments apply equally here but on the finer-grained level of a thread as opposed to (potentially multi-threaded) process. Please note that formally behavior is undefined if one tries to form a duration from two thread-time points A and B via subtraction, if A and B were obtained from different threads. Informally, the domains of the two respective threads are completely unrelated, so a difference obtained from them is meaningless and can easily be, say, negative, even though time has advanced. </p>
</td></tr>
<tr><td class="fieldname"><a id="ad61fb186191e4bb824d14601d11a2eb0a6fba12db09e5bebfaa04f6372c41c2cf" name="ad61fb186191e4bb824d14601d11a2eb0a6fba12db09e5bebfaa04f6372c41c2cf"></a>S_END_SENTINEL&#160;</td><td class="fielddoc"><p >Final, invalid clock type; its numerical value equals the number of clocks currently supported. </p>
<p >If you add or remove clock types, other places (in addition to this <code>enum</code>) to change are self-explanatory; plus update <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a959a0446aa6a0b6db59e9892d8f0a699" title="Returns the bit-set containing only those Clock_types enabled that measure passage of real (wall cloc...">Checkpointing_timer::real_clock_types()</a> and nearby functions. </p>
</td></tr>
</table>

<p class="definition">Definition at line <a class="el" href="clock__type__fwd_8hpp_source.html#l00066">66</a> of file <a class="el" href="clock__type__fwd_8hpp_source.html">clock_type_fwd.hpp</a>.</p>

</div>
</div>
<h2 class="groupheader">Function Documentation</h2>
<a id="a129032bde1082e8f2681669acf6bf03d" name="a129032bde1082e8f2681669acf6bf03d"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a129032bde1082e8f2681669acf6bf03d">&#9670;&nbsp;</a></span>operator*=()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp; operator*= </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td>
          <td class="paramname"><em>target</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">uint64_t&#160;</td>
          <td class="paramname"><em>mult_scale</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Scales each <code>Duration</code> in the target <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> by the given numerical constant. </p>
<dl class="section note"><dt>Note</dt><dd>If you plan to use division as well, always first multiply, then divide, to avoid rounding errors (assuming overflow is not a possibility).</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000145">Todo:</a></b></dt><dd>Maybe allow <code>operator*=(Duration_set)</code> by a potentially negative number; same for division.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target</td><td>The set of <code>Duration</code>s each of which may be modified. </td></tr>
    <tr><td class="paramname">mult_scale</td><td>Constant by which to multiply each <code>target</code> <code>Duration</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Reference to mutable <code>target</code> to enable standard <code>*=</code> semantics. </dd></dl>

<p class="definition">Definition at line <a class="el" href="clock__type_8cpp_source.html#l00058">58</a> of file <a class="el" href="clock__type_8cpp_source.html">clock_type.cpp</a>.</p>

</div>
</div>
<a id="a1c1e96770f8264d938ac09546a7cdb95" name="a1c1e96770f8264d938ac09546a7cdb95"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1c1e96770f8264d938ac09546a7cdb95">&#9670;&nbsp;</a></span>operator+=() <span class="overload">[1/2]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp; operator+= </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td>
          <td class="paramname"><em>target</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td>
          <td class="paramname"><em>to_add</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Advances each <code>Duration</code> in the target <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> by the given respective addend <code>Duration</code>s (negative Duration causes advancing backwards). </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target</td><td>The set of <code>Duration</code>s each of which may be modified. </td></tr>
    <tr><td class="paramname">to_add</td><td>The set of <code>Duration</code>s each of which is added to a <code>target</code> <code>Duration</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Reference to mutable <code>target</code> to enable standard <code>+=</code> semantics. </dd></dl>

<p class="definition">Definition at line <a class="el" href="clock__type_8cpp_source.html#l00038">38</a> of file <a class="el" href="clock__type_8cpp_source.html">clock_type.cpp</a>.</p>

</div>
</div>
<a id="a46efb90b848b87bb7bbaa3e415616e6e" name="a46efb90b848b87bb7bbaa3e415616e6e"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a46efb90b848b87bb7bbaa3e415616e6e">&#9670;&nbsp;</a></span>operator+=() <span class="overload">[2/2]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> &amp; flow::perf::operator+= </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> &amp;&#160;</td>
          <td class="paramname"><em>target</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td>
          <td class="paramname"><em>to_add</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Advances each <code>Time_pt</code> in the target <a class="el" href="structflow_1_1perf_1_1Time__pt__set.html" title="Convenience wrapper around an array&lt;Time_pt, N&gt;, which stores a time point for each of the N possible...">Time_pt_set</a> by the given respective addend <code>Duration</code>s (negative <code>Duration</code> causes advancing backwards). </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target</td><td>The set of <code>Time_pt</code>s each of which may be modified. </td></tr>
    <tr><td class="paramname">to_add</td><td>The set of <code>Duration</code>s each of which is added to a <code>target</code> <code>Time_pt</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Reference to mutable <code>target</code> to enable standard <code>+=</code> semantics. </dd></dl>

<p class="definition">Definition at line <a class="el" href="clock__type_8cpp_source.html#l00048">48</a> of file <a class="el" href="clock__type_8cpp_source.html">clock_type.cpp</a>.</p>

<p class="reference">References <a class="el" href="clock__type__fwd_8hpp_source.html#l00188">flow::perf::Duration_set::m_values</a>, and <a class="el" href="clock__type__fwd_8hpp_source.html#l00198">flow::perf::Time_pt_set::m_values</a>.</p>

</div>
</div>
<a id="af4b93cb0638c3d0bcfcf36903f0a3e46" name="af4b93cb0638c3d0bcfcf36903f0a3e46"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af4b93cb0638c3d0bcfcf36903f0a3e46">&#9670;&nbsp;</a></span>operator-()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> operator- </td>
          <td>(</td>
          <td class="paramtype">const <a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> &amp;&#160;</td>
          <td class="paramname"><em>to</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="structflow_1_1perf_1_1Time__pt__set.html">Time_pt_set</a> &amp;&#160;</td>
          <td class="paramname"><em>from</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Returns a <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> representing the time that passed since <code>from</code> to <code>to</code> (negative if <code>to</code> happened earlier), for each <code>Clock_type</code> stored. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">to</td><td>The minuend set of time points. </td></tr>
    <tr><td class="paramname">from</td><td>The subtrahend set of time points. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>See above. </dd></dl>

<p class="definition">Definition at line <a class="el" href="clock__type_8cpp_source.html#l00026">26</a> of file <a class="el" href="clock__type_8cpp_source.html">clock_type.cpp</a>.</p>

</div>
</div>
<a id="aff603762f38b9e3e3d50b833e09c3f91" name="aff603762f38b9e3e3d50b833e09c3f91"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aff603762f38b9e3e3d50b833e09c3f91">&#9670;&nbsp;</a></span>operator/=()</h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp; operator/= </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td>
          <td class="paramname"><em>target</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">uint64_t&#160;</td>
          <td class="paramname"><em>div_scale</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Divides each <code>Duration</code> in the target <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> by the given numerical constant. </p>
<dl class="section note"><dt>Note</dt><dd>If you plan to user multiplication as well, always first multiply, then divide, to avoid rounding errors (and assuming overflow is not a possibility).</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">target</td><td>The set of <code>Duration</code>s each of which may be modified. </td></tr>
    <tr><td class="paramname">div_scale</td><td>Constant by which to divide each <code>target</code> <code>Duration</code>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Reference to mutable <code>target</code> to enable standard <code>/=</code> semantics. </dd></dl>

<p class="definition">Definition at line <a class="el" href="clock__type_8cpp_source.html#l00068">68</a> of file <a class="el" href="clock__type_8cpp_source.html">clock_type.cpp</a>.</p>

</div>
</div>
<a id="aa26027bcba9c000350811727f0a8fc21" name="aa26027bcba9c000350811727f0a8fc21"></a>
<h2 class="memtitle"><span class="permalink"><a href="#aa26027bcba9c000350811727f0a8fc21">&#9670;&nbsp;</a></span>operator&lt;&lt;() <span class="overload">[1/4]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; flow::perf::operator&lt;&lt; </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a>&#160;</td>
          <td class="paramname"><em>clock_type</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Prints string representation of the given clock type <code>enum</code> value to the given <code>ostream</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
    <tr><td class="paramname">clock_type</td><td>Object to serialize. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="clock__type_8cpp_source.html#l00078">78</a> of file <a class="el" href="clock__type_8cpp_source.html">clock_type.cpp</a>.</p>

<p class="reference">References <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a1490431155a134162390180995550ca7">S_CPU_SYS_LO_RES</a>, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2">S_CPU_THREAD_TOTAL_HI_RES</a>, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0ac5c54159101dbdb580f0b16a9397d6f3">S_CPU_TOTAL_HI_RES</a>, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0ae06b569eb44aff6a567186f4eddb12ed">S_CPU_USER_LO_RES</a>, <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a6fba12db09e5bebfaa04f6372c41c2cf">S_END_SENTINEL</a>, and <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a8cbf506eda585c026dfb5b72c402d342">S_REAL_HI_RES</a>.</p>

</div>
</div>
<a id="a6d5b7cbbe0ec5133299f97148ef3eaa0" name="a6d5b7cbbe0ec5133299f97148ef3eaa0"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a6d5b7cbbe0ec5133299f97148ef3eaa0">&#9670;&nbsp;</a></span>operator&lt;&lt;() <span class="overload">[2/4]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; operator&lt;&lt; </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html">Checkpointing_timer</a> &amp;&#160;</td>
          <td class="paramname"><em>timer</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Prints string representation of the given <code><a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a></code> (whether with original data or an aggregated-result timer) to the given <code>ostream</code>. </p>
<p >Note this is multi-line output that does <em>not</em> end in newline.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
    <tr><td class="paramname">timer</td><td>Object to serialize. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="checkpt__timer_8cpp_source.html#l00340">340</a> of file <a class="el" href="checkpt__timer_8cpp_source.html">checkpt_timer.cpp</a>.</p>

</div>
</div>
<a id="a5bb3a068357516df714c4266ec5c3df4" name="a5bb3a068357516df714c4266ec5c3df4"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a5bb3a068357516df714c4266ec5c3df4">&#9670;&nbsp;</a></span>operator&lt;&lt;() <span class="overload">[3/4]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; operator&lt;&lt; </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="structflow_1_1perf_1_1Checkpointing__timer_1_1Checkpoint.html">Checkpointing_timer::Checkpoint</a> &amp;&#160;</td>
          <td class="paramname"><em>checkpoint</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Prints string representation of the given <code>Checkpoint</code> to the given <code>ostream</code>. </p>
<p >See <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a9e6078df059d5626ab5774f0a33fbad7" title="Records a checkpoint, which takes a sample of all enabled Clock_types&#39; clocks and records the corresp...">Checkpointing_timer::checkpoint()</a> and <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html#a1f03d654924a3724e1f051c119f3767b" title="Returns the checkpoints recorded so far.">Checkpointing_timer::checkpoints()</a>.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
    <tr><td class="paramname">checkpoint</td><td>Object to serialize. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="checkpt__timer_8cpp_source.html#l00335">335</a> of file <a class="el" href="checkpt__timer_8cpp_source.html">checkpt_timer.cpp</a>.</p>

</div>
</div>
<a id="a4cff304aa30be9d5810f90101d32b761" name="a4cff304aa30be9d5810f90101d32b761"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a4cff304aa30be9d5810f90101d32b761">&#9670;&nbsp;</a></span>operator&lt;&lt;() <span class="overload">[4/4]</span></h2>

<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">std::ostream &amp; operator&lt;&lt; </td>
          <td>(</td>
          <td class="paramtype">std::ostream &amp;&#160;</td>
          <td class="paramname"><em>os</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const <a class="el" href="structflow_1_1perf_1_1Duration__set.html">Duration_set</a> &amp;&#160;</td>
          <td class="paramname"><em>duration_set</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Prints string representation of the given <a class="el" href="structflow_1_1perf_1_1Duration__set.html" title="Convenience wrapper around an array&lt;Duration, N&gt;, which stores a duration for each of the N possible ...">Duration_set</a> value to the given <code>ostream</code>. </p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">os</td><td>Stream to which to write. </td></tr>
    <tr><td class="paramname">duration_set</td><td>Object to serialize. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd><code>os</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="clock__type_8cpp_source.html#l00093">93</a> of file <a class="el" href="clock__type_8cpp_source.html">clock_type.cpp</a>.</p>

</div>
</div>
<a id="a0dee22ec7bf250bbbf556a7e15c1f784" name="a0dee22ec7bf250bbbf556a7e15c1f784"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a0dee22ec7bf250bbbf556a7e15c1f784">&#9670;&nbsp;</a></span>timed_function()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Accumulator , typename Func &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">auto flow::perf::timed_function </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a>&#160;</td>
          <td class="paramname"><em>clock_type</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Accumulator *&#160;</td>
          <td class="paramname"><em>accumulator</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Func &amp;&amp;&#160;</td>
          <td class="paramname"><em>function</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Constructs a closure that times and executes <code>void</code>-returning <code>function()</code>, adding the elapsed time with clock type <code>clock_type</code> &ndash; as raw ticks of <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">perf::Duration</a> &ndash; to <code>accumulator</code>. </p>
<p >Consider other overload(s) and similarly named functions as well. With this one you get:</p><ul>
<li><code>function()</code> is treated as returning <code>void</code> (any return value is ignored).</li>
<li><code>function()</code> is a generally-used timed function: not necessarily a <code>boost.asio</code> or <a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">flow::async</a> <em>handler</em>. Any associated executor (such as a <code>strand</code>) <em>will</em> be lost. See <a class="el" href="namespaceflow_1_1perf.html#a7a3694bcd6e4bd506715d5931bc0c009" title="Identical to timed_function() but suitable for boost.asio-targeted handler functions.">timed_handler()</a>, if you have a handler.</li>
<li>One specific <a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0" title="Clock types supported by flow::perf module facilities, perf::Checkpointing_timer in particular.">perf::Clock_type</a>, not some subset given as <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601" title="Short-hand for a bit-set of N bits which represents the presence or absence of each of the N possible...">perf::Clock_types_subset</a>. For performance this may be significant, even though operations on the latter are still light-weight.</li>
<li>Accumulation (the plus-equals operation) done by performing <code>+=(duration_rep_t)</code>, where <a class="el" href="namespaceflow_1_1perf.html#a75b06c669e720c60621f3c68c3d34408" title="The raw type used in Duration to store its clock ticks.">perf::duration_rep_t</a> is &ndash; as a reminder &ndash; a raw integer type like <code>int64_t</code>. If accumulation may occur in a multi-threaded situation concurrently, this can improve performance vs. using an explicit lock, if one uses <code>Accumulator</code> = <code>atomic&lt;duration_rep_t&gt;</code>.</li>
<li>Lack of <code>chrono</code>-style type safety: It is up to you to interpret the <code>*accumulator</code>-stored ticks as their appropriate units.</li>
</ul>
<h3>Synopsis/examples</h3>
<p >Time a function that happens to take a couple of args. Don't worry about the timing also happening concurrenty: not using <code>atomic</code>.</p>
<div class="fragment"><div class="line"><a class="code hl_typedef" href="namespaceflow_1_1perf.html#a75b06c669e720c60621f3c68c3d34408">flow::perf::duration_rep_t</a> accumulated_ticks(0);</div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> timed_func</div>
<div class="line">  = <a class="code hl_function" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784">flow::perf::timed_function</a></div>
<div class="line">      (<a class="code hl_enumvalue" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2">flow::perf::Clock_type::S_CPU_THREAD_TOTAL_HI_RES</a>, &amp;accumulated_ticks,</div>
<div class="line">       [](<span class="keywordtype">int</span> x, <span class="keywordtype">int</span> y) { <span class="keywordflow">for</span> (<span class="keyword">auto</span> i = 0; i &lt; (x * y); ++i) {} });</div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><span class="comment">// Later, run it -- this will add to accumulated_ticks.  Can do this many times but not concurrently.</span></div>
<div class="line">timed_func(7, 7); <span class="comment">// Note it can only be called void-style.</span></div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><span class="comment">// Later, here&#39;s the result.  Note the construction from type-unsafe ticks to type-safe Duration.</span></div>
<div class="line"><span class="keyword">const</span> <a class="code hl_typedef" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456">flow::perf::Duration</a> total_dur(accumulated_ticks);</div>
<div class="line"><span class="comment">// Can convert to whatever units type-safely now (duration_cast&lt;&gt; in this case allows for precision loss).</span></div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> total_dur_us = chrono::duration_cast&lt;chrono::microseconds&gt;(total_dur);</div>
<div class="ttc" id="anamespaceflow_1_1perf_html_a0dee22ec7bf250bbbf556a7e15c1f784"><div class="ttname"><a href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784">flow::perf::timed_function</a></div><div class="ttdeci">auto timed_function(Clock_type clock_type, Accumulator *accumulator, Func &amp;&amp;function)</div><div class="ttdoc">Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...</div><div class="ttdef"><b>Definition:</b> <a href="timed__function_8hpp_source.html#l00032">timed_function.hpp:32</a></div></div>
<div class="ttc" id="anamespaceflow_1_1perf_html_a38e42ae0923eb23052e3a8a1e7956456"><div class="ttname"><a href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456">flow::perf::Duration</a></div><div class="ttdeci">Fine_duration Duration</div><div class="ttdoc">Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.</div><div class="ttdef"><b>Definition:</b> <a href="clock__type__fwd_8hpp_source.html#l00039">clock_type_fwd.hpp:39</a></div></div>
<div class="ttc" id="anamespaceflow_1_1perf_html_a75b06c669e720c60621f3c68c3d34408"><div class="ttname"><a href="namespaceflow_1_1perf.html#a75b06c669e720c60621f3c68c3d34408">flow::perf::duration_rep_t</a></div><div class="ttdeci">Duration::rep duration_rep_t</div><div class="ttdoc">The raw type used in Duration to store its clock ticks.</div><div class="ttdef"><b>Definition:</b> <a href="clock__type__fwd_8hpp_source.html#l00050">clock_type_fwd.hpp:50</a></div></div>
<div class="ttc" id="anamespaceflow_1_1perf_html_ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2"><div class="ttname"><a href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2">flow::perf::Clock_type::S_CPU_THREAD_TOTAL_HI_RES</a></div><div class="ttdeci">@ S_CPU_THREAD_TOTAL_HI_RES</div><div class="ttdoc">Similar to S_CPU_TOTAL_HI_RES but applied to the calling thread as opposed to entire process.</div></div>
</div><!-- fragment --><p >Same thing but with an <code>atomic</code> to support timing/execution occuring concurrently:</p>
<div class="fragment"><div class="line">std::atomic&lt;flow::perf::duration_rep_t&gt; accumulated_ticks(0);</div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> timed_func</div>
<div class="line">  = <a class="code hl_function" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784">flow::perf::timed_function</a></div>
<div class="line">      (<a class="code hl_enumvalue" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2">flow::perf::Clock_type::S_CPU_THREAD_TOTAL_HI_RES</a>, &amp;accumulated_ticks,</div>
<div class="line">       [](<span class="keywordtype">int</span> x, <span class="keywordtype">int</span> y) { <span class="keywordflow">for</span> (<span class="keyword">auto</span> i = 0; i &lt; (x * y); ++i) {} });</div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><span class="comment">// Later, run it -- this will add to accumulated_ticks.  Can do this many times *and* concurrently in N threads.</span></div>
<div class="line">timed_func(7, 7); <span class="comment">// Note it can only be called void-style.</span></div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><span class="comment">// Later, here&#39;s the result.  Note the construction from type-unsafe ticks to type-safe Duration.</span></div>
<div class="line"><span class="keyword">const</span> <a class="code hl_typedef" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456">flow::perf::Duration</a> total_dur(accumulated_ticks);</div>
<div class="line"><span class="comment">// Can convert to whatever units type-safely now (duration_cast&lt;&gt; in this case allows for precision loss).</span></div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> total_dur_us = chrono::duration_cast&lt;chrono::microseconds&gt;(total_dur);</div>
</div><!-- fragment --><h3><code>Accumulator A</code> type requirements/recommendations</h3>
<p >It must have <code>A += duration_rep_t(...)</code>. This operation must be safe for concurrent execution with itself, if <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a> is potentially used concurrently. In that case consider <code>atomic&lt;duration_rep_t&gt;</code>. If concurrency is not a concern, you can just use <code>duration_rep_t</code> to avoid the strict-ordering overhead involved in <code>atomic</code> plus-equals operation.</p>
<p ><code>Accumulator</code> is understood to store raw ticks of <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">Duration</a> &ndash; not actual <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">Duration</a> &ndash; for performance reasons (to wit: so that <code>atomic</code> plus-equals can be made use of, if it exists). If you need a <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">Duration</a> ultimately &ndash; and for type safety you really <em>should</em> &ndash; it is up to you to construct a <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">Duration</a> from the accumulated <code>duration_rep_t</code>. This is trivially done via the <code>Duration(duration_rep_t)</code> constructor.</p>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000146">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>, when operating on an <code>atomic&lt;duration_rep_t&gt;</code>, uses <code>+=</code> for accumulation which may be lock-free but uses strict ordering; a version that uses <code>fetch_add()</code> with relaxed ordering may be desirable for extra performance at the cost of not-always-up-to-date accumulation results in all threads. As of this writing this can be done by the user by providing a custom type that defines <code>+=</code> as explicitly using <code>fetch_add()</code> with relaxed ordering; but we could provide an API for this.</dd></dl>
<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000147">Todo:</a></b></dt><dd><a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a> overload exists for a single <code>Clock_type</code>, but simultaneous multi-clock timing using the <a class="el" href="namespaceflow_1_1perf.html#aabd93a8a40158585ed149742d8937601" title="Short-hand for a bit-set of N bits which represents the presence or absence of each of the N possible...">perf::Clock_types_subset</a> paradigm (as used, e.g., in <a class="el" href="classflow_1_1perf_1_1Checkpointing__timer.html" title="The central class in the perf Flow module, this efficiently times the user&#39;s operation,...">Checkpointing_timer</a>) would be a useful and consistent API. E.g., one could measure user and system elapsed time simultaneously. As of this writing this only does not exist due to time constraints: a perf-niggardly version targeting one clock type was necessary.</dd></dl>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Accumulator</td><td>Integral accumulator of clock ticks. See above for details. </td></tr>
    <tr><td class="paramname">Func</td><td>A function that is called <code>void</code>-style taking any arbitrary number of args, possibly none. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">clock_type</td><td>The type of clock to use for timing <code>function()</code>. </td></tr>
    <tr><td class="paramname">accumulator</td><td>The accumulator to add time elapsed when calling <code>function()</code> to. See instructions above regarding concurrency, <code>atomic</code>, etc. </td></tr>
    <tr><td class="paramname">function</td><td>The function to execute and time. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>A closure that will time and execute <code>function()</code>, adding the elapsed time to <code>accumulator</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="timed__function_8hpp_source.html#l00032">32</a> of file <a class="el" href="timed__function_8hpp_source.html">timed_function.hpp</a>.</p>

<p class="reference">References <a class="el" href="checkpt__timer_8cpp_source.html#l00241">flow::perf::Checkpointing_timer::now()</a>.</p>

<p class="reference">Referenced by <a class="el" href="timed__concurrent__task__loop_8hpp_source.html#l00332">flow::async::Timed_concurrent_task_loop_impl&lt; Time_accumulator &gt;::post()</a>, <a class="el" href="timed__concurrent__task__loop_8hpp_source.html#l00356">flow::async::Timed_concurrent_task_loop_impl&lt; Time_accumulator &gt;::schedule_at()</a>, <a class="el" href="timed__concurrent__task__loop_8hpp_source.html#l00348">flow::async::Timed_concurrent_task_loop_impl&lt; Time_accumulator &gt;::schedule_from_now()</a>, and <a class="el" href="timed__handler_8hpp_source.html#l00033">timed_handler()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceflow_1_1perf_a0dee22ec7bf250bbbf556a7e15c1f784_cgraph.svg" width="380" height="71"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceflow_1_1perf_a0dee22ec7bf250bbbf556a7e15c1f784_icgraph.svg" width="816" height="275"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a58d2f7a7fca0c3cfd0a87ae560ce4926" name="a58d2f7a7fca0c3cfd0a87ae560ce4926"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a58d2f7a7fca0c3cfd0a87ae560ce4926">&#9670;&nbsp;</a></span>timed_function_nvr()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Accumulator , typename Func &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">auto flow::perf::timed_function_nvr </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a>&#160;</td>
          <td class="paramname"><em>clock_type</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Accumulator *&#160;</td>
          <td class="paramname"><em>accumulator</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Func &amp;&amp;&#160;</td>
          <td class="paramname"><em>function</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Constructs a closure that times and executes non-<code>void</code>-returning <code>function()</code>, adding the elapsed time with clock type <code>clock_type</code> &ndash; as raw ticks of <a class="el" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456" title="Short-hand for a high-precision boost.chrono duration, formally equivalent to flow::Fine_duration.">perf::Duration</a> &ndash; to <code>accumulator</code>. </p>
<p >"Nvr" stands for non-<code>void</code>-returning.</p>
<p >Consider other overload(s) and similarly named functions as well. With this one you get:</p><ul>
<li><code>function()</code> is treated as returning non-<code>void</code> (any return value returned by it is then returned by the returned closure accordingly).<ul>
<li>Hence <code>function()</code> cannot be a <code>boost.asio</code> handler, which are always <code>void</code>-returning. So there is no <a class="el" href="namespaceflow_1_1perf.html#a7a3694bcd6e4bd506715d5931bc0c009" title="Identical to timed_function() but suitable for boost.asio-targeted handler functions.">timed_handler()</a> counterpart to the present function.</li>
</ul>
</li>
<li>Otherwise identical to the similar <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>.</li>
</ul>
<h3>Synopsis/examples</h3>
<p >Similar to the 2nd example in <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a> doc header: Time a function that happens to take a couple of args, allowing for concurrency by using an <code>atomic</code>. The difference: <code>timed_func()</code> returns a value.</p>
<div class="fragment"><div class="line">std::atomic&lt;flow::perf::duration_rep_t&gt; accumulated_ticks(0);</div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> timed_func</div>
<div class="line">  = <a class="code hl_function" href="namespaceflow_1_1perf.html#a58d2f7a7fca0c3cfd0a87ae560ce4926">flow::perf::timed_function_nvr</a></div>
<div class="line">      (<a class="code hl_enumvalue" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2">flow::perf::Clock_type::S_CPU_THREAD_TOTAL_HI_RES</a>, &amp;accumulated_ticks,</div>
<div class="line">       [](<span class="keywordtype">int</span> x, <span class="keywordtype">int</span> y) -&gt; <span class="keywordtype">int</span> { <span class="keywordflow">for</span> (<span class="keyword">auto</span> i = 0; i &lt; (x * y); ++i) {} <span class="keywordflow">return</span> i; });</div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><span class="comment">// Later, run it -- this will add to accumulated_ticks.  Can do this many times *and* concurrently in N threads.</span></div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> result = timed_func(7, 7); <span class="comment">// Note it is called non-void-style, with the return value passed-through.</span></div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><span class="comment">// Later, here&#39;s the result.  Note the construction from type-unsafe ticks to type-safe Duration.</span></div>
<div class="line"><span class="keyword">const</span> <a class="code hl_typedef" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456">flow::perf::Duration</a> total_dur(accumulated_ticks);</div>
<div class="line"><span class="comment">// Can convert to whatever units type-safely now (duration_cast&lt;&gt; in this case allows for precision loss).</span></div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> total_dur_us = chrono::duration_cast&lt;chrono::microseconds&gt;(total_dur);</div>
<div class="ttc" id="anamespaceflow_1_1perf_html_a58d2f7a7fca0c3cfd0a87ae560ce4926"><div class="ttname"><a href="namespaceflow_1_1perf.html#a58d2f7a7fca0c3cfd0a87ae560ce4926">flow::perf::timed_function_nvr</a></div><div class="ttdeci">auto timed_function_nvr(Clock_type clock_type, Accumulator *accumulator, Func &amp;&amp;function)</div><div class="ttdoc">Constructs a closure that times and executes non-void-returning function(), adding the elapsed time w...</div><div class="ttdef"><b>Definition:</b> <a href="timed__function_8hpp_source.html#l00047">timed_function.hpp:47</a></div></div>
</div><!-- fragment --><h3><code>Accumulator A</code> type requirements/recommendations</h3>
<p >See <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Accumulator</td><td>See <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>. </td></tr>
    <tr><td class="paramname">Func</td><td>A function that is called non-<code>void</code>-style taking any arbitrary number of args, possibly none. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">clock_type</td><td>The type of clock to use for timing <code>function()</code>. </td></tr>
    <tr><td class="paramname">accumulator</td><td>The accumulator to add time elapsed when calling <code>function()</code> to. See instructions above regarding concurrency, <code>atomic</code>, etc. </td></tr>
    <tr><td class="paramname">function</td><td>The function to execute and time. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>A closure that will time and execute <code>function()</code>, adding the elapsed time to <code>accumulator</code>. </dd></dl>

<p class="definition">Definition at line <a class="el" href="timed__function_8hpp_source.html#l00047">47</a> of file <a class="el" href="timed__function_8hpp_source.html">timed_function.hpp</a>.</p>

<p class="reference">References <a class="el" href="checkpt__timer_8cpp_source.html#l00241">flow::perf::Checkpointing_timer::now()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceflow_1_1perf_a58d2f7a7fca0c3cfd0a87ae560ce4926_cgraph.svg" width="402" height="71"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
<a id="a7a3694bcd6e4bd506715d5931bc0c009" name="a7a3694bcd6e4bd506715d5931bc0c009"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7a3694bcd6e4bd506715d5931bc0c009">&#9670;&nbsp;</a></span>timed_handler()</h2>

<div class="memitem">
<div class="memproto">
<div class="memtemplate">
template&lt;typename Accumulator , typename Handler &gt; </div>
      <table class="memname">
        <tr>
          <td class="memname">auto flow::perf::timed_handler </td>
          <td>(</td>
          <td class="paramtype"><a class="el" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0">Clock_type</a>&#160;</td>
          <td class="paramname"><em>clock_type</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Accumulator *&#160;</td>
          <td class="paramname"><em>accumulator</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">Handler &amp;&amp;&#160;</td>
          <td class="paramname"><em>handler</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div><div class="memdoc">

<p>Identical to <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a> but suitable for boost.asio-targeted handler functions. </p>
<p >In other words, if you want to <code>post(handler)</code> or <code>async_...(handler)</code> in a boost.asio <code>Task_engine</code>, and you'd like to time <code>handler()</code> when it is executed by boost.asio, then use <code>timed_handler(..., handler)</code>.</p>
<p >Consider other overload(s) and similarly named functions as well. With this one you get:</p><ul>
<li><code>handler()</code> is a <code>boost.asio</code> or <a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">flow::async</a> <em>handler</em>.</li>
<li>Otherwise identical to the similar <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>.</li>
</ul>
<dl class="section note"><dt>Note</dt><dd>This is suitable for using the Flow-recommended boost.asio wrapper/helper API, <a class="el" href="namespaceflow_1_1async.html" title="Flow module containing tools enabling multi-threaded event loops operating under the asynchronous-tas...">flow::async</a>. </dd></dl>
<dl class="section warning"><dt>Warning</dt><dd>Using <code>timed_function(handler)</code> would "work" too, in that it would compile and at a first glance appear to work fine. The problem: If <code>handler</code> is bound to an executor &ndash; most commonly a boost.asio strand (<a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>) &ndash; then using <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a> would "unbind it." So it it was bound to <code>Strand S</code>, meant to make certain <code>handler()</code> never executed concurrently with other handlers bound to <code>S</code>, then that constraint would (silently!) no longer be observed &ndash; leading to terrible intermittent concurrency bugs. </dd></dl>
<dl class="section note"><dt>Note</dt><dd>boost.asio handlers always return <code>void</code> (meaning anything else they might return is ignored). Hence there is no <code>timed_handler_nvr()</code>, even though there is a <a class="el" href="namespaceflow_1_1perf.html#a58d2f7a7fca0c3cfd0a87ae560ce4926" title="Constructs a closure that times and executes non-void-returning function(), adding the elapsed time w...">timed_function_nvr()</a>.</dd></dl>
<h3>Synopsis/examples</h3>
<p >Similar to the 2nd example in <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a> doc header: Time a function that happens to take a couple of args, allowing for concurrency by using an <code>atomic</code>. The difference: it is first bound to a strand. In this case we <code>post()</code> the handler, so it takes no args in this example. However, if used with, say, <code>boost::asio::ip::tcp::socket::async_read_some()</code>, it would take args such as bytes-received and error code.</p>
<div class="fragment"><div class="line"><a class="code hl_typedef" href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">flow::util::Task_engine</a> multi_threaded_engine; <span class="comment">// boost.asio Task_engine later associated with 2+ threads.</span></div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><span class="comment">// Strand guaranteeing non-concurrency for any handler functions bound to it, perhaps pertaining to HTTP request R.</span></div>
<div class="line"><a class="code hl_typedef" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e">flow::util::Strand</a> this_request_strand(multi_threaded_engine);</div>
<div class="line">std::atomic&lt;flow::perf::duration_rep_t&gt; accumulated_ticks(0);</div>
<div class="line"><span class="keyword">auto</span> timed_hnd</div>
<div class="line">  = <a class="code hl_function" href="namespaceflow_1_1perf.html#a7a3694bcd6e4bd506715d5931bc0c009">flow::perf::timed_handler</a></div>
<div class="line">      (<a class="code hl_enumvalue" href="namespaceflow_1_1perf.html#ad61fb186191e4bb824d14601d11a2eb0a93867c73fb6ef991268c0052153344c2">flow::perf::Clock_type::S_CPU_THREAD_TOTAL_HI_RES</a>, &amp;accumulated_ticks,</div>
<div class="line">       boost::asio::bind_executor(this_request_strand,</div>
<div class="line">                                  []() { <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0; i &lt; 1000000; ++i) {} });</div>
<div class="line"><span class="comment">// Post it for ASAP execution -- *when* it asynchronously executed in some thread, will add to accumulated_ticks.</span></div>
<div class="line"><span class="comment">// timed_hnd() is bound to this_request_strand, because the function we passed to timed_handler() was so bound.</span></div>
<div class="line">boost::asio::post(multi_threaded_engine, timed_hnd);</div>
<div class="line"><span class="comment">// ...</span></div>
<div class="line"><span class="comment">// Later, here&#39;s the result.  Note the construction from type-unsafe ticks to type-safe Duration.</span></div>
<div class="line"><span class="keyword">const</span> <a class="code hl_typedef" href="namespaceflow_1_1perf.html#a38e42ae0923eb23052e3a8a1e7956456">flow::perf::Duration</a> total_dur(accumulated_ticks);</div>
<div class="line"><span class="comment">// Can convert to whatever units type-safely now (duration_cast&lt;&gt; in this case allows for precision loss).</span></div>
<div class="line"><span class="keyword">const</span> <span class="keyword">auto</span> total_dur_us = chrono::duration_cast&lt;chrono::microseconds&gt;(total_dur);</div>
<div class="ttc" id="anamespaceflow_1_1perf_html_a7a3694bcd6e4bd506715d5931bc0c009"><div class="ttname"><a href="namespaceflow_1_1perf.html#a7a3694bcd6e4bd506715d5931bc0c009">flow::perf::timed_handler</a></div><div class="ttdeci">auto timed_handler(Clock_type clock_type, Accumulator *accumulator, Handler &amp;&amp;handler)</div><div class="ttdoc">Identical to timed_function() but suitable for boost.asio-targeted handler functions.</div><div class="ttdef"><b>Definition:</b> <a href="timed__handler_8hpp_source.html#l00033">timed_handler.hpp:33</a></div></div>
<div class="ttc" id="anamespaceflow_1_1util_html_aa59354ab408e978c8a7bda1a4706924e"><div class="ttname"><a href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e">flow::util::Strand</a></div><div class="ttdeci">Task_engine::strand Strand</div><div class="ttdoc">Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...</div><div class="ttdef"><b>Definition:</b> <a href="util__fwd_8hpp_source.html#l00138">util_fwd.hpp:138</a></div></div>
<div class="ttc" id="anamespaceflow_1_1util_html_ac3e89a8a271b0ddc76ac2a0ce488dea4"><div class="ttname"><a href="namespaceflow_1_1util.html#ac3e89a8a271b0ddc76ac2a0ce488dea4">flow::util::Task_engine</a></div><div class="ttdeci">boost::asio::io_context Task_engine</div><div class="ttdoc">Short-hand for boost.asio event service, the central class of boost.asio.</div><div class="ttdef"><b>Definition:</b> <a href="util__fwd_8hpp_source.html#l00135">util_fwd.hpp:135</a></div></div>
</div><!-- fragment --><h3><code>Accumulator A</code> type requirements/recommendations</h3>
<p >See <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>.</p>
<dl class="tparams"><dt>Template Parameters</dt><dd>
  <table class="tparams">
    <tr><td class="paramname">Accumulator</td><td>See <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>. </td></tr>
    <tr><td class="paramname">Handler</td><td>Handler meant to be <code>post()</code>ed or otherwise async-executed on a <code>Task_engine</code>. Can take any arbitrary number of args, possibly none. </td></tr>
  </table>
  </dd>
</dl>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">clock_type</td><td>See <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>. </td></tr>
    <tr><td class="paramname">accumulator</td><td>See <a class="el" href="namespaceflow_1_1perf.html#a0dee22ec7bf250bbbf556a7e15c1f784" title="Constructs a closure that times and executes void-returning function(), adding the elapsed time with ...">timed_function()</a>. </td></tr>
    <tr><td class="paramname">handler</td><td>The handler to execute and time. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>A closure that will time and execute <code>handler()</code>, adding the elapsed time to <code>accumulator</code>; bound to the same executor (if any; e.g., a <a class="el" href="namespaceflow_1_1util.html#aa59354ab408e978c8a7bda1a4706924e" title="Short-hand for boost.asio strand, an ancillary class that works with Task_engine for advanced task sc...">util::Strand</a>) to which <code>handler</code> is bound. </dd></dl>

<p class="definition">Definition at line <a class="el" href="timed__handler_8hpp_source.html#l00033">33</a> of file <a class="el" href="timed__handler_8hpp_source.html">timed_handler.hpp</a>.</p>

<p class="reference">References <a class="el" href="timed__function_8hpp_source.html#l00032">timed_function()</a>.</p>

<p class="reference">Referenced by <a class="el" href="timed__concurrent__task__loop_8hpp_source.html#l00392">flow::async::Timed_concurrent_task_loop_impl&lt; Time_accumulator &gt;::asio_handler_timed()</a>.</p>
<div class="dynheader">
Here is the call graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceflow_1_1perf_a7a3694bcd6e4bd506715d5931bc0c009_cgraph.svg" width="587" height="71"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>
<div class="dynheader">
Here is the caller graph for this function:</div>
<div class="dyncontent">
<div class="center"><iframe scrolling="no" frameborder="0" src="namespaceflow_1_1perf_a7a3694bcd6e4bd506715d5931bc0c009_icgraph.svg" width="595" height="59"><p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p></iframe>
</div>
</div>

</div>
</div>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Mar 28 2025 22:55:36 for Flow by&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4
</small></address>
</body>
</html>
